Skip to content

New Features: postal code, private IP override, file logging, hot-reload of mmd Database, Version Upgrades: Go (1.25) , Traefik, semantic, Fixes: Private IP Lookups, missing DB... - #13

Open
P3RF3CTION wants to merge 1 commit into
traefik-plugins:mainfrom
P3RF3CTION:main

Conversation

@P3RF3CTION

Copy link
Copy Markdown

Summary

  • Add X-GeoIP2-PostalCode header (City DB only)
  • Add X-GeoIP2-PrivateIP header — flags private/LAN/loopback IPs
  • Add private IP override via privateIPCountry / privateIPRegion / privateIPCity / privateIPPostalCode — private IPs skip the DB entirely and return operator-defined values
  • Add logFilePath config field — structured per-request log file
  • Add dbRefreshInterval config field — hot-reload of .mmdb without Traefik restart
  • Add preferXForwardedForHeader config field — use X-Forwarded-For when behind a proxy
  • Fix panic-safe DB loading — corrupt/truncated .mmdb files no longer crash the middleware
  • Fix per-instance sync.RWMutex lookup — multiple middleware instances no longer share state
  • Fix X-GeoIP2-IPAddress always reflects the resolved client IP, even when the DB is unavailable
  • Fix private IPs no longer produce spurious lookup errors in the Traefik log
  • Update base image traefik:2.4.9traefik:v3.3
  • Update go 1.19go 1.25
  • Update semantic-release ^20^24, @commitlint/config-conventional ^17^19
  • Fix .golangci.yaml — removed duplicate linter entries, replaced deprecated gomnd with mnd

New Configuration Options

Full Details see the README.md

Option Type Default Description
preferXForwardedForHeader bool false Use first IP from X-Forwarded-For instead of RemoteAddr
privateIPCountry string XX Country code returned for private/LAN/loopback IPs
privateIPRegion string XX Region code returned for private/LAN/loopback IPs
privateIPCity string XX City name returned for private/LAN/loopback IPs
privateIPPostalCode string XX Postal code returned for private/LAN/loopback IPs
dbRefreshInterval int 0 Seconds between .mmdb file change checks; 0 disables
logFilePath string (disabled) Path to per-request structured log file

New Response Headers

Header Description
X-GeoIP2-PostalCode Postal/ZIP code — City DB only, XX otherwise
X-GeoIP2-PrivateIP true when IP is private/LAN/loopback and DB was not consulted

Test Plan

  • Public IP lookup returns correct country, region, city, postal code (GeoLite2-City.mmdb)
  • Public IP lookup returns correct country, XX for region/city/postal (GeoLite2-Country.mmdb)
  • Private IP (10.x, 192.168.x, 127.x, ::1, 169.254.x) sets X-GeoIP2-PrivateIP: true
  • Private IP override config fields are reflected in response headers
  • preferXForwardedForHeader uses first entry of X-Forwarded-For
  • logFilePath creates file and writes one structured line per request
  • dbRefreshInterval reloads DB after file is replaced on disk without restart
  • Missing or corrupt .mmdb returns XX for all geo headers without crashing
  • go test ./... passes

X-GeoIP2-PostalCode header — postal/ZIP code is now populated from GeoLite2-City.mmdb and forwarded as a request header; always XX when using the Country database
X-GeoIP2-PrivateIP header — set to true when the client IP is private, loopback, or link-local and no database lookup was performed
Private IP override — new config fields privateIPCountry, privateIPRegion, privateIPCity, and privateIPPostalCode allow operator-defined location values to be returned for private/LAN IPs instead of triggering a (failing) database lookup
Per-request file logging — new logFilePath config field writes one structured line per request to a separate log file; format: <RFC3339> ip=<ip> country=<cc> region=<rc> city=<city> postal=<zip> private=<bool>
Database hot-reload — new dbRefreshInterval config field (in seconds) enables periodic checks for .mmdb file changes on disk; the new reader is swapped in atomically under a sync.RWMutex without restarting Traefik
Reverse-proxy awareness — new preferXForwardedForHeader config field uses the first IP from X-Forwarded-For instead of RemoteAddr (e.g. when running behind Cloudflare)
Panic-safe DB loading — panics from the mmdb parser (corrupt or truncated files) are caught via recover() and returned as regular errors; the middleware continues to serve requests with Unknown values
Bug Fixes
Private IPs previously caused spurious lookup errors in the Traefik log; they are now short-circuited before the database is consulted
X-GeoIP2-IPAddress was incorrectly set to XX when the database was unavailable; it now always reflects the resolved client IP regardless of lookup outcome
isPrivateIP now covers loopback (127.x, ::1) and link-local (169.254.x, fe80::) in addition to RFC 1918 ranges
Global lookup variable replaced by a per-instance field protected by sync.RWMutex — multiple middleware instances no longer share state

Internal / Chore

README.md — corrected header name X-GeoIP2-IsPrivate → X-GeoIP2-PrivateIP (3 occurrences); was inconsistent with the actual header constant in code
Dockerfile — base image updated from traefik:2.4.9 to traefik:v3.3; outdated GiGInnovationLabs references in comments updated to traefik-plugins
.traefik.yml — testData extended with all new config fields: privateIPCountry, privateIPRegion, privateIPCity, privateIPPostalCode, dbRefreshInterval, logFilePath
package.json — semantic-release bumped from ^20.1.0 to ^24.0.0; @commitlint/config-conventional bumped from ^17.4.0 to ^19.0.0; @semantic-release/github ^11.0.0 added as explicit dependency (was referenced in .releaserc.yaml but missing from package.json)
package-lock.json — removed; will be regenerated by CI on next run
.golangci.yaml — removed duplicate scopelint and ifshort entries; added mnd alongside deprecated gomnd (renamed in golangci-lint v1.56); removed deprecated empty skip-files and skip-dirs directives
Go version updated to 1.25
@P3RF3CTION P3RF3CTION changed the title New Features - postal code, private IP override, file logging, hot-reload of mmd Database, Version Upgrades Go (1.25) , Traefik, semantic New Features: postal code, private IP override, file logging, hot-reload of mmd Database, Version Upgrades: Go (1.25) , Traefik, semantic, Fixes: Private IP Lookups, missing DB... Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant